using System.Collections.Generic;
using TddGenerator.Core.Domain;
using TddGenerator.Core.Services;
using TddGenerator.Ui;
using NUnit.Framework;
using Rhino.Mocks;

namespace UnitTests.UI
{
    [TestFixture]
    public class InterfaceUnderTestPresenterTester
    {
        [Test]
        public void The_preseneter_should_close_the_vew_when_esc_key_is_pressed()
        {
            MockRepository mocks = new MockRepository();
            IInterfaceUnderTestSelectorView view = mocks.CreateMock<IInterfaceUnderTestSelectorView>();
            IProjectRepository repository = mocks.CreateMock<IProjectRepository>();
            IClassGenerator generator = mocks.CreateMock<IClassGenerator>();

            using (mocks.Record())
            {
                view.Close();
            }

            using (mocks.Playback())
            {
                InterfaceUnderTestSelectorPresenter presenter = new InterfaceUnderTestSelectorPresenter(repository, view, generator, null);
                presenter.view_EscPressed(null, null);
            }

            mocks.VerifyAll();
        }
        [Test]
        public void The_presenter_should_load_current_projects_the_first_time_addin_is_used_on_a_project()
        {
            MockRepository mocks = new MockRepository();
            IInterfaceUnderTestSelectorView view = mocks.CreateMock<IInterfaceUnderTestSelectorView>();
            IProjectRepository repository = mocks.CreateMock<IProjectRepository>();
            IDefaultSettingsRepository defaults = mocks.DynamicMock<IDefaultSettingsRepository>();


            List<string> projects = new List<string>();
            projects.Add("Core");
            projects.Add("Test");

            using (mocks.Record())
            {
                using (mocks.Unordered())
                {
                    view.CancelButtonClicked += null;
                    LastCall.IgnoreArguments();
                    view.OkButtonClicked += null;
                    LastCall.IgnoreArguments(); 
                    view.EnterPressed += null;
                    LastCall.IgnoreArguments();
                    view.EscPressed += null;
                    LastCall.IgnoreArguments();
                    Expect.Call(repository.GetProjectNames()).Return(projects).Repeat.Twice();
                    view.SetClassProjectDropdown(projects);
                    view.SetTestProjectDropdown(projects);
                }
                view.Show();
            }

            using (mocks.Playback())
            {
                InterfaceUnderTestSelectorPresenter presenter = new InterfaceUnderTestSelectorPresenter(repository,view,null, defaults);
                presenter.Load();
            }

            mocks.VerifyAll();
        }

        [Test]
        public void The_presenter_should_load_defaults_when_they_exist()
        {
            MockRepository mocks = new MockRepository();
            IInterfaceUnderTestSelectorView view = mocks.DynamicMock<IInterfaceUnderTestSelectorView>();
            IProjectRepository repository = mocks.DynamicMock<IProjectRepository>();
            IDefaultSettingsRepository defaults = mocks.CreateMock<IDefaultSettingsRepository>();


            List<string> projects = new List<string>();
            projects.Add("Core");
            projects.Add("Test");

            SetupResult.For(repository.GetProjectNames()).Return(projects);

            DefaultSettings settings = new DefaultSettings();
            settings.ClassProject = "Core";
            settings.TestProject = "Test";
            settings.Namespace = "Namespace";

            

            using (mocks.Record())
            {
                Expect.Call(defaults.Get()).Return(settings);
                using (mocks.Unordered())
                {
                    view.SetFolder(settings.Namespace);
                    view.SetClassProjectText(settings.ClassProject);
                    view.SetTestProjectText(settings.TestProject);
                }
                view.Show();
            }

            using (mocks.Playback())
            {
                InterfaceUnderTestSelectorPresenter presenter = new InterfaceUnderTestSelectorPresenter(repository, view, null,defaults);
                presenter.Load();
            }

            mocks.VerifyAll();
            
        }

        [Test]
        public void The_preseneter_should_call_class_generator_when_ok_button_is_clicked()
        {
            MockRepository mocks = new MockRepository();
            IInterfaceUnderTestSelectorView view = mocks.CreateMock<IInterfaceUnderTestSelectorView>();
            IProjectRepository repository = mocks.CreateMock<IProjectRepository>();
            IClassGenerator generator = mocks.CreateMock<IClassGenerator>();
            IDefaultSettingsRepository defaults = mocks.DynamicMock<IDefaultSettingsRepository>();
            using (mocks.Record())
            {
                Expect.Call(view.ClassProjectName).Return(string.Empty);
                Expect.Call(view.TestProjectName).Return(string.Empty);
                Expect.Call(view.FolderName).Return(new List<string>()
                {"folders"
                }
            );
                Expect.Call(view.ClassName).Return(string.Empty);

                generator.CreateClasses(null);
                LastCall.IgnoreArguments();
                view.Close();
            }

            using (mocks.Playback())
            {
                InterfaceUnderTestSelectorPresenter presenter = new InterfaceUnderTestSelectorPresenter(repository, view, generator, defaults);
                presenter.view_OkButtonClicked(null,null);
            }

            mocks.VerifyAll();
        }

        [Test]
        public void The_preseneter_should_save_defaults_before_generating_classes()
        {
            MockRepository mocks = new MockRepository();
            IInterfaceUnderTestSelectorView view = mocks.CreateMock<IInterfaceUnderTestSelectorView>();
            IProjectRepository repository = mocks.CreateMock<IProjectRepository>();
            IClassGenerator generator = mocks.CreateMock<IClassGenerator>();
            IDefaultSettingsRepository defaultsRepo = mocks.CreateMock<IDefaultSettingsRepository>();

            DefaultSettings defaults = new DefaultSettings();
            defaults.ClassProject = "class project";
            defaults.TestProject = "test project";
            defaults.Namespace = "the.folder.name";
            
            using (mocks.Record())
            {
                Expect.Call(view.ClassProjectName).Return(defaults.ClassProject);
                Expect.Call(view.TestProjectName).Return(defaults.TestProject);
                Expect.Call(view.FolderName).Return(new string[]{"the","folder","name"});
                Expect.Call(view.ClassName).Return("theclassname");

                defaultsRepo.Save(defaults);
                LastCall.IgnoreArguments();


                generator.CreateClasses(null);
                LastCall.IgnoreArguments();
                view.Close();
            }

            using (mocks.Playback())
            {
                InterfaceUnderTestSelectorPresenter presenter = new InterfaceUnderTestSelectorPresenter(repository, view, generator, defaultsRepo);
                presenter.view_OkButtonClicked(null, null);
            }

            mocks.VerifyAll();
        }

        [Test]
        public void The_preseneter_should_close_the_view_when_the_cancel_button_is_clicked()
        {
            MockRepository mocks = new MockRepository();
            IInterfaceUnderTestSelectorView view = mocks.CreateMock<IInterfaceUnderTestSelectorView>();
            IProjectRepository repository = mocks.CreateMock<IProjectRepository>();
            IClassGenerator generator = mocks.CreateMock<IClassGenerator>();

            using (mocks.Record())
            {
                view.Close();
            }

            using (mocks.Playback())
            {
                InterfaceUnderTestSelectorPresenter presenter = new InterfaceUnderTestSelectorPresenter(repository, view, generator, null);
                presenter.view_CancelButtonClicked(null, null);
            }

            mocks.VerifyAll();
        }

    }
}